package com.lfy.modules.safety.statistics.heartbeat;

import cn.hutool.extra.spring.SpringUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 心跳统计
 * @author lvfeiyang
 */
@Slf4j
public class HeartBeatCache {
    private static final Integer OUT_TIME = 15 * 1000;
    private static final Cache<String, ConcurrentHashMap<String,Long>> HEARTBEAT_CACHE = Caffeine.newBuilder()
            .initialCapacity(16)
            .expireAfterAccess(30, TimeUnit.SECONDS)
            .maximumSize(10_000)
            .build();
    private static final ThreadPoolExecutor SECONDARY_THREAD_POOL;
    static {
        SECONDARY_THREAD_POOL = SpringUtil.getBean("secondaryThreadPool");
    }
    public static void addHeartBeat(String key, String id, long timestamp) {
        Map<String,Long> beats = HEARTBEAT_CACHE.get(key, (v) -> new ConcurrentHashMap<>(16));
        Optional.ofNullable(beats).ifPresent(b -> b.put(id, timestamp));
        SECONDARY_THREAD_POOL.execute(() -> {
            assert beats != null;
           beats.forEach((k,v) -> {
               if ( v < System.currentTimeMillis() - OUT_TIME) {
                   beats.remove(k);
               }
           });
        });
    }
    public static int getOnlineCount(String key) {
        ConcurrentHashMap<String, Long> beats = HEARTBEAT_CACHE.getIfPresent(key);
        if (Objects.isNull(beats)) {
            log.info("没有心跳数据xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            return 0;
        }
       return beats.size();
    }
}
